package org.gpp.proj1.particle;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;
import java.util.StringTokenizer;

import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jmex.effects.ParticleManager;

/**
 * Parser que l� um arquivo de descri��o de part�culas e
 * retorna adequadamente os valores lidos.
 * @author Gustavo de Farias
 */
public class ParticleFileParser {

	// Conjunto de propriedades
	private Properties p;
	
	/**
	 * Cria o parser para um arquivo espec�fico;
	 * @param file O caminho do arquivo de descri��o de part�culas.
	 */
	public ParticleFileParser(String file) {

		this.p = new Properties();
		try {
			// Carrega as propriedades do arquivo.
			p.load(new FileInputStream(file));
			
		} catch (FileNotFoundException e) {

			throw new ParticleFileException("File not found: " + file);

		} catch (IOException e) {

			throw new ParticleFileException("IO Exception: " + file);
		}
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public int getParticleNumber() {
		
		return Integer.parseInt(this.p.getProperty("ParticleNumber").trim());
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public float getEmissionMaximumAngle() {
		
		return Float.parseFloat(this.p.getProperty("EmissionMaximumAngle").trim());
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public float getEmissionMinimumAngle() {
		
		return Float.parseFloat(this.p.getProperty("EmissionMinimumAngle").trim());
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public float getSpeed() {
		
		return Float.parseFloat(this.p.getProperty("Speed").trim());
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public float getParticlesMinimumLifeTime() {
		
		return Float.parseFloat(this.p.getProperty("ParticlesMinimumLifeTime").trim());
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public float getStartSize() {
		
		return Float.parseFloat(this.p.getProperty("StartSize").trim());
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public float getEndSize() {
		
		return Float.parseFloat(this.p.getProperty("EndSize").trim());
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public float getRandomMod() {
		
		return Float.parseFloat(this.p.getProperty("RandomMod").trim());
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public boolean getControlFlow() {
		
		return Boolean.parseBoolean(this.p.getProperty("ControlFlow").trim());
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public int getReleaseRate() {
		
		return Integer.parseInt(this.p.getProperty("ReleaseRate").trim());
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public float getReleaseVariance() {
		
		return Float.parseFloat(this.p.getProperty("ReleaseVariance").trim());
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public float getInitialVelocity() {
		
		return Float.parseFloat(this.p.getProperty("InitialVelocity").trim());
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public float getParticleSpinSpeed() {
		
		return Float.parseFloat(this.p.getProperty("ParticleSpinSpeed").trim());
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public int getWarmUp() {
		
		return Integer.parseInt(this.p.getProperty("warmUp").trim());
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public Vector3f getGravityForce() {
		
		StringTokenizer tokenizer = new StringTokenizer(p.getProperty("GravityForce").trim(), ", ");
		
		return new Vector3f(Float.parseFloat(tokenizer.nextToken()),
							Float.parseFloat(tokenizer.nextToken()),
							Float.parseFloat(tokenizer.nextToken()));
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public Vector3f getEmissionDirection() {
		
		StringTokenizer tokenizer = new StringTokenizer(p.getProperty("EmissionDirection").trim(), ", ");
		
		return new Vector3f(Float.parseFloat(tokenizer.nextToken()),
							Float.parseFloat(tokenizer.nextToken()),
							Float.parseFloat(tokenizer.nextToken()));
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public ColorRGBA getStartColor() {
		
		StringTokenizer tokenizer = new StringTokenizer(p.getProperty("StartColor").trim(), ", ");
		
		return new ColorRGBA(Float.parseFloat(tokenizer.nextToken()),
							Float.parseFloat(tokenizer.nextToken()),
							Float.parseFloat(tokenizer.nextToken()),
							Float.parseFloat(tokenizer.nextToken()));
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public ColorRGBA getEndColor() {
		
		StringTokenizer tokenizer = new StringTokenizer(p.getProperty("EndColor").trim(), ", ");
		
		return new ColorRGBA(Float.parseFloat(tokenizer.nextToken()),
							Float.parseFloat(tokenizer.nextToken()),
							Float.parseFloat(tokenizer.nextToken()),
							Float.parseFloat(tokenizer.nextToken()));
	}
	
	/**
	 * Obt�m a propriedade lida do arquivo de descri��o
	 * de part�culas.
	 * @return A propriedade de mesmo nome.
	 */
	public String getTexture() {
		
		return this.p.getProperty("texture").trim();
	}
	
	/**
	 * Retrieves the particle's local scale
	 * @return The particle's local scale
	 */
	public float getScale() {
		
		return Float.parseFloat(this.p.getProperty("scale").trim());
	}

	/**
	 * M�todo auxiliar para facilitar na obten��o das propriedades
	 * pelos clientes dessa classe.
	 * @param manager O gerenciador de part�culas onde as propriedades
	 * lidas por esse parser ser�o setadas.
	 */
	public void fillAttributes(ParticleManager manager) {

		manager.setGravityForce(this.getGravityForce());
		manager.setEmissionDirection(this.getEmissionDirection());
		manager.setEmissionMaximumAngle(this.getEmissionMaximumAngle());
		manager.setEmissionMinimumAngle(this.getEmissionMinimumAngle());
		manager.setSpeed(this.getSpeed());
		manager.setParticlesMinimumLifeTime(this.getParticlesMinimumLifeTime());
		manager.setStartSize(this.getStartSize());
		manager.setEndSize(this.getEndSize());
		manager.setStartColor(this.getStartColor());
		manager.setEndColor(this.getEndColor());
		manager.setRandomMod(this.getRandomMod());
		manager.setControlFlow(this.getControlFlow());
		manager.setReleaseRate(this.getReleaseRate());
		manager.setReleaseVariance(this.getReleaseVariance());
		manager.setInitialVelocity(this.getInitialVelocity());
		manager.setParticleSpinSpeed(this.getParticleSpinSpeed());
		manager.warmUp(this.getWarmUp());
	}
}